package top.zywork.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.zywork.annotation.AppAuthFilter;
import top.zywork.annotation.SysLog;
import top.zywork.annotation.XssFilter;
import top.zywork.common.*;
import top.zywork.constant.FileConstants;
import top.zywork.dto.ArticleDTO;
import top.zywork.dto.PagerDTO;
import top.zywork.enums.DatePatternEnum;
import top.zywork.enums.UploadTypeEnum;
import top.zywork.query.ArticleQuery;
import top.zywork.security.SecurityUtils;
import top.zywork.service.ArticleService;
import top.zywork.service.UploadService;
import top.zywork.vo.ArticleVO;
import top.zywork.vo.PagerVO;
import top.zywork.vo.ResponseStatusVO;

import java.util.List;

/**
 * ArticleController控制器类<br/>
 *
 * 创建于2019-07-02<br/>
 *
 * @author http://zywork.top 王振宇
 * @version 1.0
 */
@RestController
@RequestMapping("/article")
@XssFilter(ignoreUrls = {"/article/admin/save",
        "/article/admin/batch-save",
        "/article/admin/update",
        "/article/admin/batch-update"})
@AppAuthFilter(ignoreUrls = {
        "/article/admin/upload-img"
})
@Slf4j
public class ArticleController extends BaseController {

    @Value("${storage.provider}")
    private String storageProvider;

    @Value("${storage.local.compressSizes}")
    private String compressSizes;

    @Value("${storage.local.compressScales}")
    private String compressScales;

    @Value("${storage.local.article.imgParentDir}")
    private String imgParentDir;

    @Value("${storage.local.article.imgDir}")
    private String imgDir;

    @Value("${storage.local.article.imgUrl}")
    private String imgUrl;

    @Value("${storage.local.article.keepFileName}")
    private Boolean keepFileName;

    private ArticleService articleService;

    private UploadService uploadService;

    @PostMapping("admin/save")
    @SysLog(description = "后台保存ArticleVO", requestParams = false)
    public ResponseStatusVO save(@RequestBody @Validated ArticleVO articleVO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        articleVO.setCreateId(SecurityUtils.getJwtUser().getUserId());
        articleService.save(BeanUtils.copy(articleVO, ArticleDTO.class));
        return ResponseStatusVO.ok("添加成功", null);
    }

    @PostMapping("admin/batch-save")
    @SysLog(description = "后台批量保存ArticleVO", requestParams = false)
    public ResponseStatusVO saveBatch(@RequestBody @Validated List<ArticleVO> articleVOList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        for (ArticleVO articleVO : articleVOList) {
            articleVO.setCreateId(SecurityUtils.getJwtUser().getUserId());
        }
        articleService.saveBatch(BeanUtils.copyListObj(articleVOList, ArticleDTO.class));
        return ResponseStatusVO.ok("批量添加成功", null);
    }

    @GetMapping("admin/remove/{id}")
    @SysLog(description = "后台删除ArticleVO")
    public ResponseStatusVO removeById(@PathVariable("id") Long id) {
        articleService.removeById(id);
        return ResponseStatusVO.ok("删除成功", null);
    }

    @PostMapping("admin/batch-remove")
    @SysLog(description = "后台批量保存ArticleVO")
    public ResponseStatusVO removeByIds(@RequestBody String[] ids) {
        articleService.removeByIds(StringUtils.strArrayToLongArray(ids));
        return ResponseStatusVO.ok("批量删除成功", null);
    }

    @PostMapping("admin/update")
    @SysLog(description = "后台更新ArticleVO", requestParams = false)
    public ResponseStatusVO update(@RequestBody @Validated ArticleVO articleVO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        int updateRows = articleService.update(BeanUtils.copy(articleVO, ArticleDTO.class));
        if (updateRows == 1) {
            return ResponseStatusVO.ok("更新成功", null);
        } else {
            return ResponseStatusVO.dataError("数据版本号有问题，在此更新前数据已被更新", null);
        }
    }

    @PostMapping("admin/batch-update")
    @SysLog(description = "后台批量更新ArticleVO", requestParams = false)
    public ResponseStatusVO updateBatch(@RequestBody @Validated List<ArticleVO> articleVOList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        articleService.updateBatch(BeanUtils.copyListObj(articleVOList, ArticleDTO.class));
        return ResponseStatusVO.ok("批量更新成功", null);
    }

    @PostMapping("admin/active")
    @SysLog(description = "后台激活或冻结ArticleVO")
    public ResponseStatusVO active(@RequestBody ArticleVO articleVO) {
        articleService.update(BeanUtils.copy(articleVO, ArticleDTO.class));
        return ResponseStatusVO.ok("激活或冻结成功", null);
    }

    @PostMapping("admin/batch-active")
    @SysLog(description = "后台批量激活或冻结ArticleVO")
    public ResponseStatusVO activeBatch(@RequestBody @Validated List<ArticleVO> articleVOList) {
        articleService.updateBatch(BeanUtils.copyListObj(articleVOList, ArticleDTO.class));
        return ResponseStatusVO.ok("批量激活或冻结成功", null);
    }

    @GetMapping("admin/one/{id}")
    public ResponseStatusVO getById(@PathVariable("id") Long id) {
        ArticleVO articleVO = new ArticleVO();
        Object obj = articleService.getById(id);
        if (obj != null) {
            articleVO = BeanUtils.copy(obj, ArticleVO.class);
        }
        return ResponseStatusVO.ok("查询成功", articleVO);
    }

    /**
     * 用户查询单个文章
     * @param id
     * @return
     */
    @GetMapping("user/one/{id}")
    public ResponseStatusVO userGetById(@PathVariable("id") Long id) {
        return getById(id);
    }

    @GetMapping("admin/all")
    public ResponseStatusVO listAll() {
        PagerDTO pagerDTO = articleService.listAll();
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), ArticleVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/all-cond")
    public ResponseStatusVO listAllByCondition(@RequestBody ArticleQuery articleQuery) {
        PagerDTO pagerDTO = articleService.listAllByCondition(articleQuery);
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), ArticleVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/pager-cond")
    public ResponseStatusVO listPageByCondition(@RequestBody ArticleQuery articleQuery) {
        PagerDTO pagerDTO = articleService.listPageByCondition(articleQuery);
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), ArticleVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    /**
     * 用户条件查询文章
     * @param articleQuery
     * @return
     */
    @PostMapping("user/pager-cond")
    public ResponseStatusVO userListPageByCondition(@RequestBody ArticleQuery articleQuery) {
        return listPageByCondition(articleQuery);
    }

    @PostMapping("admin/upload-img")
    @SysLog(description = "后台上传文章图片", requestParams = false)
    public ResponseStatusVO upload(MultipartFile file) {
        String date = DateFormatUtils.format(DateUtils.currentDate(), DatePatternEnum.DATE.getValue());
        UploadUtils.UploadOptions uploadOptions = UploadUtils.UploadOptions.builder().uploadParentDir(imgParentDir).uploadDir(imgDir + FileConstants.SEPARATOR + date)
                .dbSaveUrl(imgUrl + FileConstants.SEPARATOR + date).keepFileName(keepFileName).build();
        uploadOptions.generateCompressSizes(compressSizes);
        return uploadService.uploadFile(storageProvider, file, UploadTypeEnum.IMAGE.getAllowedExts(), UploadTypeEnum.IMAGE.getMaxSize(), uploadOptions);
    }

    @Autowired
    public void setArticleService(ArticleService articleService) {
        this.articleService = articleService;
    }

    @Autowired
    public void setUploadService(UploadService uploadService) {
        this.uploadService = uploadService;
    }
}
